package model.protocol;

import model.client.request.*;
import model.entity.Message;
import io.netty.buffer.ByteBuf;
import model.serializer.JsonSerializer;
import model.serializer.Serializer;
import server.response.AllIdResponseMessage;
import server.response.CreateGroupResponseMessage;
import server.response.SendToIndividualsResponseMessage;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 *
 * @Description 实现具体编码和解码的方法
 * @author czc
 */
public class PacketCodec {

    public static final int MAGIC_NUMBER = 1234567;
    public static final PacketCodec INSTANCE = new PacketCodec();

    private final Map<Byte, Class<? extends AbstractPacket>> packetType =
                                    new ConcurrentHashMap<>();
    private final Map<Byte, Serializer> serializerMap =
                                    new ConcurrentHashMap<>();

    private PacketCodec() {
        packetType.put(Command.CREATE_GROUP_REQUEST, CreateGroupRequestMessage.class);
        packetType.put(Command.CREATE_GROUP_RESPONSE, CreateGroupResponseMessage.class);
        packetType.put(Command.ALLID_REQUEST, AllIdRequestMessage.class);
        packetType.put(Command.ALLID_RESPONSE, AllIdResponseMessage.class);
        packetType.put(Command.CHAT_MESSAGE, Message.class);
        packetType.put(Command.LOGIN_MESSAGE, LoginRequestMessage.class);
        packetType.put(Command.SEND_TO_GROUP_MESSAGE, SendToGroupRequestMessage.class);
        packetType.put(Command.SEND_TO_INDIVIDUALS_REQUEST, SendToIndividualsRequestMessage.class);
        packetType.put(Command.SEND_TO_INDIVIDUALS_RESPONSE, SendToIndividualsResponseMessage.class);

        //设置编码形式使用json
        Serializer serializer = new JsonSerializer();
        //
        serializerMap.put(serializer.getSerializerAlgorithm(), serializer);
    }

    public void encode(ByteBuf byteBuf, AbstractPacket packet) {
        //将packet中的数据通过json转化成byte
        byte[] bytes = Serializer.DEFAULT.serialize(packet);

        //编码过程
        //魔数
        byteBuf.writeInt(MAGIC_NUMBER);
        //版本号
        byteBuf.writeByte(packet.getVersion());
        //序列化算法，默认为
        byteBuf.writeByte(Serializer.DEFAULT.getSerializerAlgorithm());
        //数据包中传输的命令
        byteBuf.writeByte(packet.getCommand());
        //序列化后数据的长度
        byteBuf.writeInt(bytes.length);
        //将序列化后的数据写入ByteBuf
        byteBuf.writeBytes(bytes);

    }

    public AbstractPacket decode(ByteBuf byteBuf) {
        //跳过魔数
        byteBuf.skipBytes(4);
        //跳过版本号
        byteBuf.skipBytes(1);
        //获取算法
        byte serializerAlgorithm = byteBuf.readByte();
        //命令
        byte command = byteBuf.readByte();
        //数据包长度
        int len = byteBuf.readInt();
        //读取数据
        byte[] bytes = new byte[len];
        byteBuf.readBytes(bytes);

        //获取命令对应的对象，进行传输
        Class<? extends AbstractPacket> type = getPacketType(command);
        Serializer serializer = getSerializer(serializerAlgorithm);
        //默认使用json进行序列化
        if(type != null && serializer != null) {
            return serializer.deserializer(type, bytes);
        }
        return null;
    }

    private Serializer getSerializer(byte serializerAlgorithm) {

        return serializerMap.get(serializerAlgorithm);
    }
    private Class<? extends AbstractPacket> getPacketType(byte command) {

        return packetType.get(command);
    }

}
